#ifndef __CC1101_H__
#define __CC1101_H__

#include "gpio.h"
#include "spi.h"
#include "stm32f1xx_hal.h"

// 寄存器
//GDO设置
#define CC1101_IOCFG2                     0x00
#define CC1101_IOCFG1                     0x01
#define CC1101_IOCFG0                     0x02

//ADC保留,空中波特率小于100kbps时,要设置
#define CC1101_FIFOTHR                    0x03
#define ADC_RETENTION                   0x40

#define CC1101_SYNC1                      0x04
#define CC1101_SYNC0                      0x05
#define CC1101_PKTLEN                     0x06

//CRC自动弃包,接收地址设定
#define CC1101_PKTCTRL1                   0x07
#define CRC_AUTOFLUSH                   0x80
#define APPEND_STATUS                   0x04
#define ADR_ALL                         0x00
#define ADR_NO_BROAD                    0x01
#define ADR_BROAD0                      0x02
#define ADR_BROAD_0_255                 0x03

//数据白化,CRC,包格式
#define CC1101_PKTCTRL0                   0x08
#define WHITE_DATA                      0x40
#define CRC_ENABLE                      0x04
#define FIX_LEN                         0x00
#define VARIABLE_LEN                    0x01
#define INFINITE_LEN                    0x02

//地址频道
#define CC1101_ADDR                       0x09
#define CC1101_CHANNR                     0x0A

//IF频率
#define CC1101_FSCTRL1                    0x0B
#define CC1101_FSCTRL0                    0x0C

//基频设定,由RF Studio 7去生成
#define CC1101_FREQ2                      0x0D
#define CC1101_FREQ1                      0x0E
#define CC1101_FREQ0                      0x0F

//配置空中波特率和带通滤波器带宽
#define CC1101_MDMCFG4                    0x10
#define CC1101_MDMCFG3                    0x11

//DC滤波(偏向节能还是高灵敏度);调制模式 2FSK, GFSK, ASK, 4FSK;曼彻斯特编码;同步模式
#define CC1101_MDMCFG2                    0x12

//前导符字节数,频道间隔
#define CC1101_MDMCFG1                    0x13
#define CC1101_MDMCFG0                    0x14

//用多少频率偏移代表0和1
#define CC1101_DEVIATN                    0x15

//是否在RSSI小于多少时关闭RX模式???
#define CC1101_MCSM2                      0x16

//是否等待信道禁空, 发送完和接收完进入什么模式
#define CC1101_MCSM1                      0x17

//何时根据信号调整频率偏移,晶振起用后,等待稳定的时间,反应到CHP_RDYn上,强制晶振在睡眠时也启用
#define CC1101_MCSM0                      0x18

//CS拉低是是否锁定频率偏移等. 收到信号前频率补偿步进值??收到信号后什么补偿值? 频率补偿最大值
#define CC1101_FOCCFG                     0x19

//看不懂的AGC等控制
#define CC1101_BSCFG                      0x1A
#define CC1101_AGCCTRL2                   0x1B
#define CC1101_AGCCTRL1                   0x1C
#define CC1101_AGCCTRL0                   0x1D

//无线唤醒设置
#define CC1101_WOREVT1                    0x1E
#define CC1101_WOREVT0                    0x1F
#define CC1101_WORCTRL                    0x20

//PA控制等
#define CC1101_FREND1                     0x21
#define CC1101_FREND0                     0x22

//VCO什么设定,看不懂
#define CC1101_FSCAL3                     0x23
#define CC1101_FSCAL2                     0x24
#define CC1101_FSCAL1                     0x25
#define CC1101_FSCAL0                     0x26
#define CC1101_RCCTRL1                    0x27
#define CC1101_RCCTRL0                    0x28
#define CC1101_FSTEST                     0x29
#define CC1101_PTEST                      0x2A
#define CC1101_AGCTEST                    0x2B
#define CC1101_TEST2                      0x2C
#define CC1101_TEST1                      0x2D
#define CC1101_TEST0                      0x2E

// 命令
#define CC1101_SRES         0x30
#define CC1101_SFSTXON      0x31
#define CC1101_SXOFF        0x32
#define CC1101_SCAL         0x33
#define CC1101_SRX          0x34
#define CC1101_STX          0x35
#define CC1101_SIDLE        0x36
#define CC1101_SAFC         0x37
#define CC1101_SWOR         0x38
#define CC1101_SPWD         0x39
#define CC1101_SFRX         0x3A
#define CC1101_SFTX         0x3B
#define CC1101_SWORRST      0x3C
#define CC1101_SNOP         0x3D

// 状态只读寄存器
#define CC1101_PARTNUM      0x30
#define CC1101_VERSION      0x31
#define CC1101_FREQEST      0x32
#define CC1101_LQI          0x33
#define CC1101_RSSI         0x34
#define CC1101_MARCSTATE    0x35
#define CC1101_WORTIME1     0x36
#define CC1101_WORTIME0     0x37
#define CC1101_PKTSTATUS    0x38
#define CC1101_VCO_VC_DAC   0x39
#define CC1101_TXBYTES      0x3A
#define CC1101_RXBYTES      0x3B

//MARCSTATE的各种状态值
#define STATE_SLEEP                         0x00
#define STATE_IDLE                          0x01
#define STATE_XOFF                          0x02
#define STATE_VCOON_MC                      0x03
#define STATE_REGON_MC                      0x04
#define STATE_MANCAL                        0x05
#define STATE_VCOON                         0x06
#define STATE_REGON                         0x07
#define STATE_STARTCAL                      0x08
#define STATE_BWBOOST                       0x09
#define STATE_FS_LOCK                       0x0A
#define STATE_IFADCON                       0x0B
#define STATE_ENDCAL                        0x0C
#define STATE_RX                            0x0D
#define STATE_RXEND                         0x0E
#define STATE_RXRST                         0x0F
#define STATE_TXRX_SWITCH                   0x10
#define STATE_RXFIFO_OVERFLOW               0x11
#define STATE_FSTXON                        0x12
#define STATE_TX                            0x13
#define STATE_TX_END                        0x14
#define STATE_RXTX_SWITCH                   0x15
#define STATE_TXFIFO_UNDERFLOW              0x16

// 特殊多字节寄存器
#define CC1101_PATABLE      0x3E
#define CC1101_TXFIFO       0x3F
#define CC1101_RXFIFO       0x3F

//掩码
#define BYTES_IN_RXFIFO     0x7F            //接收缓冲区有效字节
#define CRC_OK              0x80            //CRC_OK在载荷最后一字节中的位置
#define BROAD_ALL           0x00            //收所有包
#define BROAD_NO            0x01            //不收所有广播
#define BROAD_0             0x02            //只收地址为0的广播
#define BROAD_0AND255       0x03            //收地址为0和255的广播

//SPI命令某些位含义
#define WRITE_BURST         0x40            //写多个
#define READ_SINGLE         0x80            //读单个
#define READ_BURST          0xC0            //读多个

#define PA_TABLE                            {0xC2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}

typedef enum
{
    BROADCAST,
    ADDRESS_CHECK
} CC1101_TxDataModeType;

//片选
#define NSS_HIGH                            SPI1_NSS_GPIO_Port->ODR |= SPI1_NSS_Pin
#define NSS_LOW                             SPI1_NSS_GPIO_Port->ODR &= (uint32_t)( ~((uint32_t)SPI1_NSS_Pin ))

//命令
#define CC1101_Rx_Mode                      CC1101_Write_Cmd(CC1101_SRX)
#define CC1101_Tx_Mode                      CC1101_Write_Cmd(CC1101_STX)
#define CC1101_Set_Idle_Mode                CC1101_Write_Cmd(CC1101_SIDLE)
#define CC1101_Set_Address(addr)            CC1101_Write_Reg(CC1101_ADDR,addr)
#define CC1101_Get_Address(addr)            CC1101_Read_Reg(CC1101_ADDR,addr)
#define CC1101_Clear_RxBuffer               CC1101_Write_Cmd(CC1101_SIDLE);CC1101_Write_Cmd(CC1101_SFRX )
#define CC1101_Clear_TxBuffer               CC1101_Write_Cmd(CC1101_SIDLE);CC1101_Write_Cmd(CC1101_SFTX )
#define CC1101_Get_RxCounter                (CC1101_Read_Status(CC1101_RXBYTES)&BYTES_IN_RXFIFO)
#define CC1101_Set_CH(ch)                   CC1101_Write_Reg(CC1101_CHANNR,ch)

//CC1101的功能实现
void C1101_WOR_Init( void );
void CC1101_Set_Address_Mode(uint8_t AddressMode);
void CC1101_Tx_Packet(uint8_t TxSize, uint8_t *pTxBuff );
void CC1101_Reset( void );
void CC1101_Init( void );

//CC1101的SPI命令
void CC1101_Write_Cmd( uint8_t Command );
void CC1101_Write_Reg( uint8_t Addr, uint8_t WriteValue );
void CC1101_Write_Multi_Reg( uint8_t Addr, uint8_t *pWriteBuff, uint8_t WriteSize );
uint8_t CC1101_Read_Reg( uint8_t Addr );
void CC1101_Read_Multi_Reg( uint8_t Addr, uint8_t *pReadBuff, uint8_t ReadSize );
uint8_t CC1101_Read_Status( uint8_t Addr );
#endif
